#include "DCTool.h"
#include "DCDevice.h"

#include <iostream>
#include <iomanip>


dc1394_t             *DCTool::dc   = NULL;
dc1394camera_list_t *DCTool::list = NULL;


bool DCTool::init()
{
  if( dc ){
    printInfo(WARNING, "DCTool already initialize");
    return true;
  }
  
  dc = dc1394_new();
  if( !dc ){
    printInfo(ERROR, "DCTool cant't initialize");
    return false;
  }

  dc1394error_t err;

  err = dc1394_camera_enumerate(dc, &list);
  if( err != DC1394_SUCCESS ){
    printInfo(ERROR, "Failed to enumerate cameras");
    return false;
  }

  if( list->num == 0 ){
    printInfo(ERROR, "No cameras found");
    return false;
  }
  
  return true;
}


void DCTool::finish()
{
  dc1394_camera_free_list(list);
  dc1394_free(dc);
}


void DCTool::printInfo(STATUS_TYPE type, const char* text)
{
  switch(type){
  case INFO:
    std::cout << "[I]: " << text << std::endl;
    break;
  case WARNING:
    std::cout << "\x1b[43m";
    std::cout << "[W]: " << text;
    std::cout << "\x1b[49m" << std::endl;
    break;
  case ERROR:
    std::cerr << "\x1b[41m";
    std::cerr << "[W]: " << text;
    std::cerr << "\x1b[49m" << std::endl;
    break;
  default:
    std::cout << "[-]: " << text << std::endl;
    break;
  }
}


void DCTool::printCameraList()
{
  if( !list ){
    printInfo(ERROR, "DCTool hasn't been initialized yet");
    return;
  }

  dc1394camera_t *camera;

  for(int i=0; i<(int)list->num; i++){
    camera = dc1394_camera_new(dc, list->ids[i].guid);
    if( !camera ){
      printInfo(ERROR, "Failed to get camera information");
      return;
    }

    std::cout << "UID-" << i << " : " << camera->vendor 
	      << " " << camera->model << std::endl;
    
    dc1394_camera_free(camera);
  }
}


DCDevice* DCTool::createDevice(int uid)
{
  if( !list ){
    printInfo(ERROR, "DCTool hasn't been initialized yet");
    return NULL;
  }

  dc1394camera_t* camera;
  dc1394error_t   err;

  camera = dc1394_camera_new(dc, list->ids[uid].guid);
  if( !camera ){
    printInfo(ERROR, "Failed to connect camera device");
    return NULL;
  }

  err = dc1394_reset_bus(camera);
  if( err != DC1394_SUCCESS ){
    printInfo(ERROR, "Failed to reset bus");
    return NULL;
  }

  err = dc1394_camera_reset(camera);
  if( err != DC1394_SUCCESS ){
    printInfo(ERROR, "Failed to reset camera");
    return NULL;
  }

  DCDevice* device = new DCDevice;
  
  device->camera = camera;

  return device;
}
